﻿using Microsoft.ExtendedReflection.Metadata;
using Microsoft.ExtendedReflection.Monitoring;
using Microsoft.ExtendedReflection.Utilities;
using Microsoft.ExtendedReflection.Utilities.Safe;
using Microsoft.ExtendedReflection.Utilities.Safe.Diagnostics;
using Microsoft.Moles.Engine;
using MolesVS2012.Host.Host;
using System;
using System.IO;
using System.Reflection;

namespace MolesVS2012.Host
{
    public static class Program
    {
        [LoaderOptimization(LoaderOptimization.MultiDomain)]
        public static int Main(string[] args)
        {
            string molesBinPath = Environment.GetEnvironmentVariable("MolesBinPath");
            if (!string.IsNullOrEmpty(molesBinPath))
                AppDomain.CurrentDomain.AssemblyResolve += (ResolveEventHandler)((s, a) =>
                {
                    string[] local_5 = new string[2]
          {
            ".dll",
            ".exe"
          };
                    foreach (string item_0 in local_5)
                    {
                        string temp_35 = a.Name;
                        char[] temp_41 = new char[1]
            {
              ','
            };
                        string local_3 = Path.Combine(molesBinPath, temp_35.Split(temp_41)[0] + item_0);
                        if (File.Exists(local_3))
                            return Assembly.LoadFile(local_3);
                    }
                    return (Assembly)null;
                });
            return Program.InternalMain(args);
        }

        private static int InternalMain(string[] args)
        {
            SafeDebugger.BreakIf(MolesVsHostEnvironmentSettings.BreakOnHostStart.Value);
            Console.WriteLine("Microsoft Moles Visual Studio Unit Test Host Type v{0}", (object)AttributeHelper.GetAssemblyFileVersion(MetadataFromReflection.GetAssembly(typeof(Program).Assembly)));
            Console.WriteLine();
            if (args == null)
                return -1003;
            try
            {
                if (args.Length == 2)
                {
                    if (args[0] == "/register")
                    {
                        Console.WriteLine("Registering Host Type for Visual Studio {0}", (object)args[1]);
                        VsHostRegistration.Register(args[1]);
                        return 0;
                    }
                    else if (args[0] == "/unregister")
                    {
                        Console.WriteLine("Unregistering Host Type for Visual Studio {0}", (object)args[1]);
                        VsHostRegistration.Unregister(args[1]);
                        return 0;
                    }
                    else if (args[0] == "/pkgdef")
                    {
                        Console.WriteLine("Generating Host Type Package Definition for Visual Studio 2010 at {0}", (object)args[1]);
                        return 0;
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("FAILED to register or unregister");
                Console.WriteLine((object)ex);
                return -1030;
            }
            if (!ControllerEnvironment.IsMonitoringEnabled)
            {
                Console.WriteLine();
                Console.WriteLine("Critical Failure: the Pex CLR profiler was not attached to the process.");
                Console.WriteLine("\tPlease consult the 'Profiler Not Attached' page in the documentation for further details.");
                return -1014;
            }
            else if (args.Length != 1 || SafeString.IsNullOrEmpty(args[0]))
            {
                Console.WriteLine();
                return -1003;
            }
            else
            {
                int num = 0;
                try
                {
                    string str1 = args[0];
                    using (_ProtectingThreadContext.Acquire())
                    {
                        using (MolesHostEngine molesHostEngine = new MolesHostEngine())
                            molesHostEngine.GetService<MolesHostRemotingManager>().Ping();
                    }
                    string directoryName1 = Path.GetDirectoryName(typeof(Program).Assembly.Location);
                    string directoryName2 = Path.GetDirectoryName(directoryName1);
                    string str2 = Path.Combine(directoryName2, "PublicAssemblies");
                    string binariesDirectory = MolesInstallHelper.GetBinariesDirectory();
                    using (_ProtectingThreadContext.Acquire())
                        Environment.CurrentDirectory = Path.GetDirectoryName(Path.GetFullPath(str1));
                    SandboxAppDomain sandboxAppDomain = (SandboxAppDomain)null;
                    try
                    {
                        MolesHostEngine molesHostEngine = (MolesHostEngine)null;
                        using (_ProtectingThreadContext.Acquire())
                        {
                            sandboxAppDomain = SandboxAppDomain.Create(str1, (string)null, SandboxTrust.FullTrust, LoaderOptimization.MultiDomain, (string[])null, new string[4]
              {
                str2,
                directoryName1,
                directoryName2,
                binariesDirectory
              });
                            AssemblyResolver resolver = sandboxAppDomain.Resolver;
                            resolver.AddAssemblyPath(typeof(Program).Assembly.FullName, typeof(Program).Assembly.Location);
                            molesHostEngine = sandboxAppDomain.CreateInstance<MolesHostEngine>();
                            molesHostEngine.AddAssemblyResolver(resolver);
                        }
                        num = molesHostEngine.Execute();
                    }
                    finally
                    {
                        IDisposable disposable = (IDisposable)sandboxAppDomain;
                        if (disposable != null)
                            disposable.Dispose();
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Moles VsHost FAILED: unexpected exception");
                    Console.WriteLine((object)ex);
                    num = -1030;
                }
                if (MolesVsHostEnvironmentSettings.CreateWindow.Value)
                {
                    Console.WriteLine("press ENTER to close this windows...");
                    Console.ReadLine();
                }
                return num;
            }
        }
    }
}